﻿using System.Collections;
using System.Collections.Generic;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business
{
    public abstract class PrimitiveCachableService<T>:CachableServiceBase<T>
         where T : class
    {
        protected PrimitiveCachableService(string cacheKey) : base(cacheKey)
        {
        }

        protected virtual IEnumerable<T> GetAllData()
        {
            return GetAllData(null);
        }

        protected virtual IEnumerable<T> GetAllData(ITransaction transaction)
        {
            var keys = GetCache<ArrayList>(CacheKey);
            if (keys == null)
            {
                var allData = OnLoadAllData(transaction);
                if (allData == null)
                {
                    SetCache(CacheKey, null);
                    return null;
                }
                keys = new ArrayList();
                foreach (var data in allData)
                {
                    var key = GetDataKey(data);
                    SetCache(GenerateCacheKey(key), data);
                    keys.Add(key);
                }
                SetCache(CacheKey, keys);
                return allData;
            }
            var listData = new List<T>();
            foreach (var key in keys)
            {
                listData.Add(GetData(key, transaction));
            }
            return listData;
        }

        protected abstract IEnumerable<T> OnLoadAllData(ITransaction transaction);

        protected override void OnAddDataComplete(object key, T data)
        {
            base.OnAddDataComplete(key, data);
            var keys = GetCache<ArrayList>(CacheKey);
            if (keys == null)
            {
                return;
            }
            // If the cache for data keys have been expired, it will be loaded from database again. And then the added key would be included in the id list.
            if (!keys.Contains(key))
            {
                keys.Add(key);
            }
            SetCache(CacheKey, keys);
        }

        protected override void OnRemoveDataComplete(object key, T data)
        {
            base.OnRemoveDataComplete(key, data);
            var keys = GetCache<ArrayList>(CacheKey);
            if (keys != null)
            {
                if (keys.Contains(key))
                {
                    keys.Remove(key);
                }
                SetCache(CacheKey, keys);
            }
        }
    }
}
